using RAG.Application.Interfaces;
using RAG.Application.Dtos;
using RAG.Application.Commands;
using RAG.Domain.Interfaces;
using RAG.Domain.Entities.App;
using RAG.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace RAG.Application.Services;

/// <summary>
/// 角色服务实现
/// </summary>
public class AppRoleService : IAppRoleService
{
    private readonly RagDbContext _db;
    private readonly IDomainEventPublisher _eventPublisher;

    public AppRoleService(
        RagDbContext db,
        IDomainEventPublisher eventPublisher)
    {
        _db = db;
        _eventPublisher = eventPublisher;
    }

    /// <summary>
    /// 获取角色列表（分页）
    /// </summary>
    public async Task<ApiResult> GetRolesAsync(int page, int size, string? search = null)
    {
        try
        {
            var query = _db.Roles
                .Include(r => r.Permissions)
                .Include(r => r.Users)
                .Where(r => !r.IsDeleted) // 只查询未删除的角色
                .AsQueryable();

            // 定义搜索条件 - 支持角色名称和描述搜索
            Func<IQueryable<Role>, string, IQueryable<Role>> searchPredicate = (q, term) =>
                q.Where(r => 
                    r.RoleName.Contains(term) || 
                    (r.RoleDescription != null && r.RoleDescription.Contains(term)));

            // 定义排序条件 - 使用稳定的排序方式，避免启用禁用后上下跳动
            Func<IQueryable<Role>, IQueryable<Role>> orderBy = q => 
                q.OrderBy(r => r.RoleName).ThenBy(r => r.Id);

            // 使用分页工具 - 一行代码完成分页、搜索、排序
            var pagedResult = await query.ToPagedResultAsync(
                page, 
                size, 
                searchPredicate, 
                search, 
                orderBy);

            // 转换为DTO
            var roleDtos = pagedResult.Items.Select(r => new RoleDetailDto
            {
                Id = r.Id,
                RoleName = r.RoleName,
                RoleDescription = r.RoleDescription,
                CreatedAt = r.CreatedAt,
                UpdatedAt = r.UpdatedAt,
                UserCount = r.Users.Count,
                PermissionCount = r.Permissions.Count,
                IsActive = r.IsActive,
                Permissions = r.Permissions.Select(p => new PermissionDto
                {
                    Id = p.Id,
                    PermissionCode = p.PermissionCode,
                    PermissionName = p.PermissionName,
                    PermissionDescription = p.PermissionDescription
                }).ToList()
            }).ToList();

            // 创建最终结果 - 包含完整的分页信息
            var result = new
            {
                Roles = roleDtos,
                Total = pagedResult.Total,
                Page = pagedResult.Page,
                Size = pagedResult.Size,
                TotalPages = pagedResult.TotalPages,
                HasPreviousPage = pagedResult.HasPreviousPage,
                HasNextPage = pagedResult.HasNextPage
            };

            return ApiResult.Success("获取角色列表成功", result);
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取角色列表时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 根据ID获取角色详情
    /// </summary>
    public async Task<ApiResult> GetRoleByIdAsync(Guid roleId)
    {
        try
        {
            var role = await _db.Roles
                .Include(r => r.Permissions)
                .Include(r => r.Users)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            var roleDto = new RoleDetailDto
            {
                Id = role.Id,
                RoleName = role.RoleName,
                RoleDescription = role.RoleDescription,
                CreatedAt = role.CreatedAt,
                UpdatedAt = role.UpdatedAt,
                UserCount = role.Users.Count,
                Permissions = role.Permissions.Select(p => new PermissionDto
                {
                    Id = p.Id,
                    PermissionCode = p.PermissionCode,
                    PermissionName = p.PermissionName,
                    PermissionDescription = p.PermissionDescription
                }).ToList()
            };

            return ApiResult.Success("获取角色详情成功", roleDto);
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取角色详情时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 创建角色
    /// </summary>
    public async Task<ApiResult> CreateRoleAsync(CreateRoleDto dto)
    {
        try
        {
            // 验证角色名称唯一性
            if (await _db.Roles.AnyAsync(r => r.RoleName == dto.RoleName))
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "角色名称已存在");

            // 创建角色
            var role = new Role
            {
                RoleName = dto.RoleName,
                RoleDescription = dto.RoleDescription,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };

            _db.Roles.Add(role);
            await _db.SaveChangesAsync();

            // 分配权限
            if (dto.PermissionIds != null && dto.PermissionIds.Any())
            {
                var permissions = await _db.Permissions.Where(p => dto.PermissionIds.Contains(p.Id)).ToListAsync();
                foreach (var permission in permissions)
                {
                    role.Permissions.Add(permission);
                }
                await _db.SaveChangesAsync();
            }

            return ApiResult.Success("角色创建成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"创建角色时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 更新角色
    /// </summary>
    public async Task<ApiResult> UpdateRoleAsync(Guid roleId, UpdateRoleDto dto)
    {
        try
        {
            var role = await _db.Roles
                .Include(r => r.Permissions)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            // 验证角色名称唯一性
            if (!string.IsNullOrEmpty(dto.RoleName) && dto.RoleName != role.RoleName)
            {
                if (await _db.Roles.AnyAsync(r => r.RoleName == dto.RoleName))
                    return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "角色名称已存在");
                role.RoleName = dto.RoleName;
            }

            // 更新其他字段
            if (!string.IsNullOrEmpty(dto.RoleDescription))
                role.RoleDescription = dto.RoleDescription;

            role.UpdatedAt = DateTime.UtcNow;

            // 更新权限
            if (dto.PermissionIds != null)
            {
                role.Permissions.Clear();
                var permissions = await _db.Permissions.Where(p => dto.PermissionIds.Contains(p.Id)).ToListAsync();
                foreach (var permission in permissions)
                {
                    role.Permissions.Add(permission);
                }
            }

            await _db.SaveChangesAsync();

            return ApiResult.Success("角色更新成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"更新角色时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 删除角色（软删除）
    /// </summary>
    public async Task<ApiResult> DeleteRoleAsync(Guid roleId)
    {
        try
        {
            var role = await _db.Roles
                .Include(r => r.Users)
                .Where(r => !r.IsDeleted) // 只查询未删除的角色
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            // 检查是否有用户使用此角色
            if (role.Users.Any())
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "该角色下还有用户，无法删除");

            // 软删除：设置IsDeleted为true
            role.IsDeleted = true;
            role.UpdatedAt = DateTime.UtcNow;
            await _db.SaveChangesAsync();

            return ApiResult.Success("角色删除成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除角色时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 启用角色
    /// </summary>
    public async Task<ApiResult> EnableRoleAsync(Guid roleId)
    {
        try
        {
            var role = await _db.Roles
                .Where(r => !r.IsDeleted)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            if (role.IsActive)
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "角色已经是启用状态");

            role.IsActive = true;
            role.UpdatedAt = DateTime.UtcNow;
            await _db.SaveChangesAsync();

            return ApiResult.Success("角色启用成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"启用角色时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 禁用角色
    /// </summary>
    public async Task<ApiResult> DisableRoleAsync(Guid roleId)
    {
        try
        {
            var role = await _db.Roles
                .Where(r => !r.IsDeleted)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            if (!role.IsActive)
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "角色已经是禁用状态");

            role.IsActive = false;
            role.UpdatedAt = DateTime.UtcNow;
            await _db.SaveChangesAsync();

            return ApiResult.Success("角色禁用成功");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"禁用角色时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取角色权限
    /// </summary>
    public async Task<ApiResult> GetRolePermissionsAsync(Guid roleId)
    {
        try
        {
            var role = await _db.Roles
                .Include(r => r.Permissions)
                .Where(r => !r.IsDeleted)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            var permissions = role.Permissions
                .Where(p => !p.IsDeleted && p.IsActive)
                .Select(p => new PermissionDto
                {
                    Id = p.Id,
                    PermissionCode = p.PermissionCode,
                    PermissionName = p.PermissionName,
                    PermissionDescription = p.PermissionDescription
                })
                .OrderBy(p => p.PermissionCode)
                .ToList();

            var result = new
            {
                RoleId = role.Id,
                RoleName = role.RoleName,
                RoleDescription = role.RoleDescription,
                Permissions = permissions,
                PermissionCount = permissions.Count
            };

            return ApiResult.Success("获取角色权限成功", result);
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取角色权限时发生错误: {ex.Message}");
        }
    }

    /// <summary>
    /// 为角色分配权限
    /// </summary>
    public async Task<ApiResult> AssignPermissionsAsync(Guid roleId, AssignPermissionsDto dto)
    {
        try
        {
            // 验证输入
            if (dto.PermissionIds == null || !dto.PermissionIds.Any())
            {
                return ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "权限ID列表不能为空");
            }

            // 查找角色
            var role = await _db.Roles
                .Include(r => r.Permissions)
                .Where(r => !r.IsDeleted)
                .FirstOrDefaultAsync(r => r.Id == roleId);

            if (role == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "角色不存在");

            // 验证权限是否存在且未删除
            var permissions = await _db.Permissions
                .Where(p => !p.IsDeleted && p.IsActive && dto.PermissionIds.Contains(p.Id))
                .ToListAsync();

            if (permissions.Count != dto.PermissionIds.Count)
            {
                var foundPermissionIds = permissions.Select(p => p.Id).ToList();
                var missingPermissionIds = dto.PermissionIds.Except(foundPermissionIds).ToList();
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, $"以下权限不存在: {string.Join(", ", missingPermissionIds)}");
            }

            // 清除角色现有权限
            role.Permissions.Clear();

            // 分配新权限
            foreach (var permission in permissions)
            {
                role.Permissions.Add(permission);
            }

            role.UpdatedAt = DateTime.UtcNow;
            await _db.SaveChangesAsync();

            return ApiResult.Success($"成功为角色分配了 {permissions.Count} 个权限");
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"分配权限时发生错误: {ex.Message}");
        }
    }
} 